#include <iostream>
#include <fstream>
#include <png.h>

#include <iomanip>
#include <chrono>
#include <sstream>

#include "imageIO.h"
#include "../system/log.h"

namespace Image
{
    std::string ImageSaver::get_now_time(std::time_t timestamp_collection){
        std::tm* now_tm = std::localtime(&timestamp_collection);
        std::ostringstream oss;
        oss << std::put_time(now_tm, "%Y-%m-%d_%H:%M:%S");
        return oss.str();
    }

    bool ImageSaver::save_image_as_png(unsigned char *data_image, int64_t timestamp_collection, int width, int height, int bit_depth, int color_type){
        int stride = width * 3;

        std::string file_path;
        FILE *file_stream;

        png_structp png_ptr;
        png_infop info_ptr;

        // 以当前时间命名文件
        std::stringstream ss;
        std::string time = get_now_time(timestamp_collection);
        ss << this->_folder_name << '/' << time << ".png";
        file_path = ss.str();

        // 打开文件流
        file_stream = fopen(file_path.c_str(), "wb");
        if (!file_stream){
            THROW_EXCEPTION(std::runtime_error, "Could not open file [", file_path, "]");
        }

        // png 写结构体
        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
        if (!png_ptr){
            fclose(file_stream);
            THROW_EXCEPTION(std::runtime_error,"Could not create png writer struct");
        }

        // png 信息结构体 保存图像的宽、高、颜色类型
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr) {
            png_destroy_write_struct(&png_ptr, NULL);
            fclose(file_stream);
            THROW_EXCEPTION(std::runtime_error, "Could not create PNG info structure");
        }

        // 错误处理
        if (setjmp(png_jmpbuf(png_ptr))) {
            png_destroy_write_struct(&png_ptr, NULL);
            fclose(file_stream);
            THROW_EXCEPTION(std::runtime_error, "Could not set jump for PNG error handling");
        }

        png_init_io(png_ptr, file_stream);
        
        // 写png文件头
        png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type,
                     PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
        png_write_info(png_ptr, info_ptr);

        // 把buffer的数据写到图像中
        png_bytep row_pointers[height];
        for (int y = 0; y < height; y++) {
            row_pointers[y] = data_image + y * stride;
        }

        png_write_image(png_ptr, row_pointers);
        png_write_end(png_ptr, nullptr);

        // 清理
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(file_stream);
        return true;
    }
} // namespace Image

      










